package model

import (
	"encoding/json"
	"fmt"
	"gorm.io/gorm/clause"
	"server/common"
	"server/pkg/app"
	"server/pkg/cron"
)

type Btask struct {
	ID   int    `gorm:"primaryKey;"`
	Name string `gorm:"column:name;not null;type:varchar(16);unique" json:"name"`
}

type BaseTask struct {
	Model
	Name string `gorm:"column:name;not null;type:varchar(16);unique" json:"name"`

	Slice int `gorm:"column:slice;not null;type:int;default:1" json:"slice"` //分片
}

type Task struct {
	BaseTask
	cron.Cron

	Group bool `gorm:"column:group;type:bool;default:false" json:"group"`

	Branch        string `gorm:"column:branch;not null;type:varchar(32);default:main" json:"branch"`
	RetryStrategy uint   `gorm:"column:retry_strategy;not null;type:int" json:"retryStrategy"`

	OwnerID int   `json:"owner_id"`
	Owner   Owner `gorm:"references:ID"`

	ProjectID int     `json:"project_id"`
	Project   Project `gorm:"references:ID"`

	Env json.RawMessage `gorm:"column:env;type:json" json:"env"`

	Users []Owner `gorm:"many2many:user_task;ForeignKey:ID;References:ID"`

	TaskGroupStr json.RawMessage `gorm:"column:taskgroups;type:json"`
	Param        json.RawMessage `gorm:"column:param;type:json"`
}

type TaskGroup struct {
	Name   string  `json:"name"`
	RunWay string  `json:"runway"`
	Tasks  []Tasks `json:"tasks"`
}

type TaskApi struct {
	Task
	TaskGroups []TaskGroup `json:"taskgroup"`
}

func (task *Btask) TableName() string {
	return "task"
}
func (task *Task) TableName() string {
	return "task"
}

func (task *Task) SName() string {
	return "任务"
}

func (task *Btask) Info() error {
	if err := common.DB.Omit(clause.Associations).Where("id = ?", task.ID).Find(&task); err != nil {
		return err.Error
	}
	return nil
}

func (task *Task) List(page *app.Page) ([]Task, int64) {
	tasks := []Task{}
	var count int64
	if err := common.DB.Preload(clause.Associations).Order("id desc").Limit(page.Size).Offset((page.Page - 1) * page.Size).Find(&tasks).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
		return tasks, count
	}
	return tasks, count
}

func (task *Task) Info() {
	if err := common.DB.Where("name = ?", task.Name).Preload(clause.Associations).Find(&task).Error; err != nil {
		fmt.Println(err)
	}
}

func (task *Task) Create() error {
	if err := common.DB.Debug().Create(&task).Error; err != nil {
		return err
	}
	return nil
}

func (task *Task) Update() error {
	if err := common.DB.Debug().Where("name = ?", task.Name).Updates(&task).Error; err != nil {
		return err
	}
	return nil
}

func (task *Task) SwitchCron() error {
	if err := common.DB.Model(Task{}).Debug().Where("name = ?", task.Name).Update("switch", task.Switch).Error; err != nil {
		panic(err)
	}
	return nil
}

func (task *Task) Delete() error {
	if err := common.DB.Where("name = ?", task.Name).Delete(&task).Error; err != nil {
		return err
	}
	return nil
}
